/**
 *  Serponix is an arcade game in focus to multiplayer based on the classic game Snake.
 *  Copyright (C) 2010 - 2011  Daniel Vala
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License,
 *  or  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  If you have any question do not hesitate to contact author
 *  on e-mail address: danielvala42@gmail.com
 */
package com.serponix.game.editor;

import com.serponix.gui.WindowInterface;
import com.serponix.game.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * Model pro editor map.
 * Obsahuje aktuálně kreslenou mapu a metody pro její kreslení, mazání, uložení a načtení.
 * Model obsahuje i View pro vykreslování.
 * @author Daniel Vala
 */
public class ModelEditor extends JPanel {

    private Mapa mapa;
    private int sirkaHernihoPanelu;
    private int vyskaHernihoPanelu;
    private WindowInterface okno;

    public ModelEditor(WindowInterface okno, MessagePanel panelZprav) {
        this.okno = okno;
        mapa = new Mapa();
        sirkaHernihoPanelu = 1099;
        vyskaHernihoPanelu = 599;
        panelZprav.addMessage(String.format("Pro návrat do menu stisknite ESCAPE"));
        panelZprav.addMessage(String.format("Pro smazání mapy stisknite DELETE"));
        panelZprav.addMessage(String.format("Pro uložení mapy stisknite S"));
        panelZprav.addMessage(String.format("Pro načtení mapy stisknite L"));
    }

    public int getSirka() {
        return sirkaHernihoPanelu;
    }

    public int getVyska() {
        return vyskaHernihoPanelu;
    }

    /**
     * Ukončí editor map a vrátí se zpět do menu.
     */
    public void ukonciEditor() {
        okno.displayMenu();
    }

    /**
     * Přidá stěnu mapy (zeď) do celé mapy.
     * Zeď zarovná do desítkové mřížky.
     * Nelze přidat zeď mimo herní plochu.
     * @param x X souřadnice zdi.
     * @param y Y souřadnice zdi.
     */
    public void pridejStenuMapy(int x, int y) {
        x = (int) (x / (getWidth() / new Double(getSirka()))) / 10;
        y = (int) (y / (getHeight() / new Double(getVyska()))) / 10;
        // ošetření, aby se nedalo kreslit mimo herní plochu
        if (x >= 0 && x <= sirkaHernihoPanelu && y >= 0 && y <= vyskaHernihoPanelu) {
            mapa.pridejZed(x, y);
        }
    }

    /**
     * Vymaže zeď zadaných souřadnicích.
     * @param x Souřadnice zdi X.
     * @param y Souřadnice zdi Y.
     */
    public void vymazStenuMapy(int x, int y) {
        x = (int) (x / (getWidth() / new Double(getSirka()))) / 10;
        y = (int) (y / (getHeight() / new Double(getVyska()))) / 10;
        mapa.smazZed(x, y);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
        g2d.scale(getWidth() / (double) getSirka(), getHeight() / (double) getVyska());
        mapa.kresliMapu(g2d);
    }

    /**
     * Načte mapu ze souboru na aktuální plochu.
     * @return Název načtené mapy.
     */
    public String nactiMapu() {
        JFileChooser fc = new JFileChooser();
        fc.addChoosableFileFilter(new FileNameExtensionFilter("Soubory s příponou *.ser", "ser"));
        fc.setCurrentDirectory(new File(Mapa.getPath()));
        String zobrazenyNazevMapy = null;
        if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
            zobrazenyNazevMapy = fc.getSelectedFile().getName().substring(0, fc.getSelectedFile().getName().length() - 4);
            try {
                mapa.nactiMapu(zobrazenyNazevMapy, new FileInputStream(fc.getSelectedFile()));
            } catch (FileNotFoundException ex) {
                JOptionPane.showMessageDialog(null, "Zvolený soubor neexistuje.", "Chyba", JOptionPane.ERROR_MESSAGE);
            }
        }
        return zobrazenyNazevMapy;
    }

    /**
     * Uloží aktuální mapu z plochy do souboru.
     */
    public void ulozMapu() {
        String nazevMapy = JOptionPane.showInputDialog(this, "Zadejte název mapy", "ULOŽENÍ MAPY", JOptionPane.QUESTION_MESSAGE);
        if (nazevMapy != null) {
            boolean uspech = mapa.ulozMapu(nazevMapy);
            if (uspech) {
                JOptionPane.showMessageDialog(this, "Mapa byla úspěšně uložena do souboru " + nazevMapy + ".ser", "Úspěch", JOptionPane.INFORMATION_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(this, "Mapu se nepodařilo uložit.", "Chyba", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    /**
     * Smaže aktuální mapu z plochy.
     */
    public void smazMapu() {
        Object[] options = {"Ano", "Ne"};
        int vyber = JOptionPane.showOptionDialog(null,
                "Opravdu chcete smazat tuto mapu?", "Upozornění",
                JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
                options, options[1]);
        if (vyber != 0) {
            return;
        }
        mapa.smazCelouMapu();
    }
}
